package com.start.admin.security;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.start.admin.entity.StartSysMenu;
import com.start.admin.entity.StartSysUser;
import com.start.admin.service.*;
import com.start.common.constant.StartConstant;
import com.start.common.details.BaseUserDetails;
import com.start.common.entity.StartBaseEntity;
import com.start.common.entity.StartBaseMenu;
import com.start.common.entity.StartBaseRole;
import com.start.common.user.UserManageInfoService;
import com.start.common.vo.SysMenuDataRulesVo;
import com.start.security.details.IStartBaseUserDetailsService;
import com.start.security.handler.IStartPermissionLoad;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class StartAdminUserDetailService extends IStartBaseUserDetailsService implements UserManageInfoService<StartSysUser>, IStartPermissionLoad {
    @Autowired
    private StartSysUserService sysUserService;


    @Autowired
    private StartSysUserRoleService userRoleService;

    @Autowired
    private StartSysRoleService sysRoleService;
    @Autowired
    private StartSysRoleDataRuleService roleDataRuleService;
    @Autowired
    private StartSysMenuService sysMenuService;


    @Override
    public BaseUserDetails startLoadUserByUsername(String userName) {
        StartSysUser sysUser = sysUserService.getByUserName(userName);
        if (sysUser == null) throw new UsernameNotFoundException("userName:" + userName + " not found");
        return new StartAdminUserDetails(sysUser);
    }

    @Override
    public String getLoadUserType() {
        return getUserType();
    }

    /**
     * 用户类型
     *
     * @return
     */
    @Override
    public String getUserType() {
        return StartConstant.ClientUserType.ADMIN_USER;
    }

    /**
     * 用户菜单
     *
     * @param userDetails
     * @return
     */
    @Override
    public <T extends StartBaseMenu> List<T> getUserMenus(BaseUserDetails userDetails) {
        List<T> list;
        if (userDetails.isSuperUser()) {
            list = (List<T>) sysMenuService.list(new LambdaQueryWrapper<StartSysMenu>().orderByAsc(StartBaseMenu::getSort));
        } else {
            list = (List<T>) sysMenuService.listByUserId(userDetails.getUserId());
        }
        return list;
    }

    /**
     * 用户角色
     *
     * @param userDetails
     * @return
     */
    @Override
    public <T extends StartBaseRole> List<T> getUsrRoles(BaseUserDetails userDetails) {
        if (!userDetails.isSuperUser()) {
            return (List<T>) userRoleService.getRoleListByUserId(userDetails.getUserId());
        }
        return (List<T>) sysRoleService.list();
    }

    /**
     * 获取菜单规则
     *
     * @param userDetails
     * @return
     */
    @Override
    public List<SysMenuDataRulesVo> getMenuDataRules(BaseUserDetails userDetails) {
        if (userDetails.isSuperUser()) return new ArrayList<>();
        return roleDataRuleService.listByUserId(userDetails.getUserId());
    }

    /**
     * 判断用户是否拥有权限
     *
     * @param userDetails
     * @param permissions
     * @return
     */
    @Override
    public boolean hasPermission(BaseUserDetails userDetails, String... permissions) {
        if (userDetails.isSuperUser()) return true;
        return sysMenuService.userHasPermissions(userDetails.getUserId(), permissions);
    }

    /**
     * 判断用户是否拥有角色
     *
     * @param userDetails
     * @param roles
     * @return
     */
    @Override
    public boolean hasRoles(BaseUserDetails userDetails, String... roles) {
        if (userDetails.isSuperUser()) return true;
        return userRoleService.userHasRoles(userDetails.getUserId(), roles);
    }

    /**
     * 根据组件获取菜单规则
     *
     * @param userDetails
     * @param component
     * @return
     */
    @Override
    public List<SysMenuDataRulesVo> getUserMenuDataRulesByComponent(BaseUserDetails userDetails, String component) {
        if (userDetails.isSuperUser()) return new ArrayList<>();
        return roleDataRuleService.listByUserIdAndComponent(userDetails, component);
    }

    /**
     * @param userDetails   根据动态表单id组件获取菜单规则
     * @param dynamicFormId
     * @return
     */
    @Override
    public List<SysMenuDataRulesVo> getUserMenuDataRulesByDynamicFormId(BaseUserDetails userDetails, String dynamicFormId) {
        if (userDetails.isSuperUser()) return new ArrayList<>();
        return roleDataRuleService.listByUserIdAndDynamicFormId(userDetails, dynamicFormId);
    }


    /**
     * 获取用户好友信息
     *
     * @param ids
     * @return
     */
    @Override
    public List<StartSysUser> getByUserIds(Collection<? extends Serializable> ids) {
        LambdaQueryWrapper<StartSysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(StartBaseEntity::getId, ids);
        return sysUserService.list(lambdaQueryWrapper);
    }

    @Override
    public StartSysUser getByUserId(Serializable userId) {
        return sysUserService.getById(userId);
    }
}
